package com.atguigu.tingshu.album.task;


import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.BaseCategoryService;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.user.client.UserClientFeign;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.RBloomFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/***
 * 专辑数据预热到redis的定时任务
 */
//@Component
@Log4j2
public class AlbumFromMysqlToRedisTask {

    // 每页处理的数据量
    public static final Integer SIZE = 1000;

    @Autowired
    AlbumInfoService albumInfoService;
    @Autowired
    UserClientFeign userClientFeign;
    @Autowired
    BaseCategoryService baseCategoryService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    RBloomFilter rBloomFilter;


    /**
     * 将专辑+专辑统计+专辑作者写入redis的定时任务
     */
//    @Scheduled(cron = "* * 1 * * *")
    @Scheduled(cron = "10/10 * * * * *")
    public void albumFromMysqlToRedis() {
        // 查询DB中可用的专辑数据数量：is_deleted=0
        long count = albumInfoService.count();
        // 计算循环查询的次数 -- 分页查询：指定每页处理的数据量：1000
        long size = count % SIZE == 0 ? (count / SIZE) : (count / SIZE) + 1;
        // 循环查询
        for (int i = 1; i <= size; i++) {
            // 本次循环处理的专辑数据(指定分页)
            List<AlbumInfo> records = albumInfoService.page(new Page<>(i, SIZE)).getRecords();
            // foreach循环写入redis
            records.stream().forEach(albumInfo -> {
                // 专辑数据 key与AlbumFeign里写入Redis的相同，value--JSONObject类型
                redisTemplate.opsForValue().set("getAlbumInfo:" + Arrays.asList(albumInfo.getId().toString()),
                        JSONObject.toJSONString(albumInfo),
                        // 一天过期
                        60 * 24 * 10, TimeUnit.MINUTES);
                // 将专辑存入布隆过滤器
                rBloomFilter.add("getAlbumInfo:" + Arrays.asList(albumInfo.getId().toString()));
                // 查询每个专辑的统计数据
                Map<String, Object> albumStatMap = albumInfoService.getAlbumStatMap(albumInfo.getId());
                // 写入Redis
                redisTemplate.opsForValue().set("getAlbumStatMap:" + Arrays.asList(albumInfo.getId().toString()),
                        JSONObject.toJSONString(albumStatMap),
                        60 * 24 * 10, TimeUnit.MINUTES);

                // 作者数据 -- feign API有Cache增强 无需另外手动写入Redis
                userClientFeign.getUserInfo(albumInfo.getUserId());
            });
        }
    }


    /**
     * 将分类数据写入redis的定时任务
     */
//    @Scheduled(cron = "* * 1 * * *")
    @Scheduled(cron = "10/10 * * * * *")
    public void categoryFromMysqlToRedis() {
        // 查询分类数据list后foreach遍历写入Redis
        baseCategoryService.list().stream().forEach(baseCategoryView -> {
            redisTemplate.opsForValue().set("getBaseCategoryView:" + Arrays.asList(baseCategoryView.getCategory3Id().toString()),
                    JSONObject.toJSONString(baseCategoryView),
                    60 * 24 * 10, TimeUnit.MINUTES);
        });
    }

}

